package com.acme.team03.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.acme.team03.messages.Message;
import com.acme.team3.chat.SendCommandHandler;

public class Connection implements Runnable {

	private static Logger log = Logger.getLogger(Connection.class.getName());

	private Socket socket;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	private volatile boolean isClosed;
	private MessageHandler msgHandler;
	private int id;

	public Connection(int id, Socket socket, MessageHandler msgHandler)
			throws IOException {
		this.id = id;
		this.socket = socket;
		out = new ObjectOutputStream(socket.getOutputStream());
		out.flush();
		in = new ObjectInputStream(socket.getInputStream());
		this.msgHandler = msgHandler;
	}

	public void run() {
		while (!isClosed) {
			try {
				Object obj = in.readObject();
				Message msg = (Message) obj;
				msgHandler.handleMessage(msg);
			} catch (ClassNotFoundException e) {
				log.log(Level.SEVERE, e.toString());
				close();
			} catch (IOException e) {
				log.log(Level.SEVERE, Arrays.toString(e.getStackTrace()));
				close();
			} catch (InterruptedException e) {
				log.log(Level.WARNING, e.toString());
				close();
			}
		}
	}
	
	public void sendMessage(Message msg) throws IOException {
		if (!isClosed)
			out.writeObject(msg);
	}
	
	public Message receiveMessage() throws IOException {
		try {
			if (!isClosed)
				return (Message) in.readObject();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public void close() {
		isClosed = true;
		try {
			if (in != null)
				in.close();
			if (out != null)
				out.close();
			if (socket != null)
				socket.close();
		} catch (IOException e) {
			log.log(Level.SEVERE, e.toString());
		}
	}

	public void setID(int id) {
		this.id = id;
		
	}

	public int getID() {
		return id;
	}

}
